package com.example.demo.utils;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.metadata.CellExtra;

import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;

import com.example.demo.ao.Attendance;
import com.example.demo.mapper.AttendanceMapper;
import lombok.extern.slf4j.Slf4j;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
public class AttendanceDataListener implements ReadListener<Attendance> {

    private static final int BATCH_COUNT = 1000;
    private List<Attendance> cachedList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

    private final AttendanceMapper attendanceMapper;


    //储存行合并信息
    private final ConcurrentMap<Integer, Integer> mergeInfo = new ConcurrentHashMap<>();
    //记录当前处理行
    private final AtomicInteger rowIndex = new AtomicInteger(0);
    //表头
    private int headRowNumber = 1;

    public AttendanceDataListener(AttendanceMapper attendanceMapper) {
        this.attendanceMapper = attendanceMapper;
    }


    @Override
    public void extra(CellExtra extra, AnalysisContext context){
        if (extra.getType() == CellExtraTypeEnum.MERGE){
            int startRow = extra.getFirstRowIndex();
            int endRow = extra.getLastRowIndex();
            int mergeRows = endRow - startRow;

            //处理第三第四
            if (mergeRows > 0 && startRow == headRowNumber + 2){
                mergeInfo.put(startRow, mergeRows);
                log.info("起始行={}， 结束行={}", startRow, mergeRows);
            }
        }
    }




    @Override
    public void invoke(Attendance data, AnalysisContext context) {
        // 获取表头行数（在第一次调用时设置）
        if (headRowNumber == 0) {
            headRowNumber = context.readSheetHolder().getHeadRowNumber();
        }

        int currentRow = rowIndex.getAndIncrement();
        int actualDataRowIndex = currentRow + headRowNumber;
        try {
            // 检查是否为第三行和第四行的合并区域
            if (isTargetMergedSubRow(actualDataRowIndex)) {
                log.debug("跳过合并区域空行: row={}", actualDataRowIndex);
                return; // 直接跳过不处理
            }


            // 跳过空行
            if (data.getUserName() == null || data.getUserName().trim().isEmpty()) {
                return;
            }

            // 处理日期时间
            processDateTime(data);

            // 计算状态
            data.setStatus(calculateStatus(data));

            // 设置创建时间
            Date now = new Date();
            data.setCreateTime(now);
            data.setUpdateTime(now);

            cachedList.add(data);
            if (cachedList.size() >= BATCH_COUNT) {
                saveData();
                cachedList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
                System.out.println(cachedList);
            }
        } catch (Exception e) {
            log.error("处理数据异常: {}", data, e);
        }
    }


    // 只检查第三行和第四行的合并区域
    private boolean isTargetMergedSubRow(int rowIndex) {
        for (Map.Entry<Integer, Integer> entry : mergeInfo.entrySet()) {
            int startRow = entry.getKey();
            int mergeRows = entry.getValue();
            int endRow = startRow + mergeRows;

            // 当前行在合并区域内但不是起始行（第三行）
            if (rowIndex > startRow && rowIndex <= endRow) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        saveData();
        log.info("所有数据解析完成！");
    }

    private void saveData() {
        if (!cachedList.isEmpty()) {
            attendanceMapper.batchInsert(cachedList);
            log.info("ymy");
        }
    }


    private String getCell(Map<Integer, String> rowData, int index) {
        String val = rowData.get(index);
        return val == null ? null : val.trim();
    }



    private String calculateStatus(Attendance data) {
        // 从Excel导入的数据中获取打卡结果
        String clockInStatus = data.getClockInStatus(); // 上班打卡结果
        String clockOutStatus = data.getClockOutStatus(); // 下班打卡结果

        // 如果clockInStatus或clockOutStatus为空，则不做处理，返回null
        if (clockInStatus == null && clockOutStatus == null) {
            return null;
        }

        // 如果clockInStatus或clockOutStatus为空，则设为未打卡（10）
        if (clockInStatus == null || clockOutStatus == null) {
            return "10";
        }
//        00-正常，01-迟到，02-早退，03-缺勤，04-事假，05-病假，06-旷工,10-未打卡,11-补卡通过,12-外勤,07-调休，13-其他，14-年假，15-婚假，16-产假，17-陪产假，18-路途假
        // 根据业务规则计算状态
        if ("正常".equals(clockInStatus) && "正常".equals(clockOutStatus)) {
            return "00"; // 正常

        } else if ("缺卡".equals(clockInStatus) && "缺卡".equals(clockOutStatus)) {
            return "06"; // 旷工
        } else if ("缺卡".equals(clockInStatus) || "缺卡".equals(clockOutStatus)) {
            return "03"; // 缺勤
        } else if ("未打卡".equals(clockInStatus) || "未打卡".equals(clockOutStatus)) {
            return "10";
        } else if ("迟到".equals(clockInStatus)) {
            return "01"; // 迟到
        } else if ("早退".equals(clockOutStatus)) {
            return "02"; // 早退
        } else if ("请假".equals(clockInStatus) || "请假".equals(clockOutStatus) || "事假".equals(clockInStatus) || "事假".equals(clockOutStatus)) {
            return "04"; // 事假
        }else if ("调休".equals(clockInStatus) || "调休".equals(clockOutStatus)) {
            return "07"; // 事假
        } else if (clockInStatus.contains("外勤") || clockOutStatus.contains("外勤")) {
            return "12"; // 事假
        } else if (clockInStatus.contains("补卡审批通过") || clockOutStatus.contains("补卡审批通过")) {
            return "11"; // 事假
        }else if (clockInStatus.contains("年假") || clockOutStatus.contains("年假")) {
            return "14"; // 事假
        }else if (clockInStatus.contains("婚假") || clockOutStatus.contains("婚假")) {
            return "15"; // 事假
        }else if (clockInStatus.contains("产假") || clockOutStatus.contains("产假")) {
            return "16"; // 事假
        }else if (clockInStatus.contains("陪产假") || clockOutStatus.contains("陪产假")) {
            return "17"; // 事假
        }else if (clockInStatus.contains("路途假") || clockOutStatus.contains("路途假")) {
            return "18"; // 事假
        }else {
            return "13";
        }
    }


    private void processDateTime(Attendance data) {
        try {
            // 创建时区设置
            TimeZone shanghaiTimeZone = TimeZone.getTimeZone("Asia/Shanghai");

            // 1. 处理日期 (25-06-01 星期日 → 2025-06-01)
            if (data.getOriginalDateStr() != null) {
                // 提取日期部分（去掉星期）
                String datePart = data.getOriginalDateStr().split(" ")[0].trim();

                // 处理两位数的年份 (25 → 2025)
                String[] dateParts = datePart.split("-");
                if (dateParts.length == 3) {
                    String year = "20" + dateParts[0]; // 假设是2000年以后的日期
                    String month = dateParts[1];
                    String day = dateParts[2];

                    // 创建标准日期格式
                    String standardDate = String.format("%s-%s-%s", year, month, day);
                    SimpleDateFormat destFormat = new SimpleDateFormat("yyyy-MM-dd");
                    destFormat.setTimeZone(shanghaiTimeZone); // 设置时区
                    data.setAttendanceDate(destFormat.parse(standardDate));
                }
            }

            // 2. 处理上班时间 (09:58 → 当天日期+时间)
            if (data.getClockInTimeStr() != null && !data.getClockInTimeStr().isEmpty()) {
                if (data.getAttendanceDate() != null) {
                    SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
                    dateFormatter.setTimeZone(shanghaiTimeZone); // 设置时区

                    SimpleDateFormat timeFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                    timeFormatter.setTimeZone(shanghaiTimeZone); // 设置时区

                    String dateStr = dateFormatter.format(data.getAttendanceDate());
                    Date inTime = timeFormatter.parse(dateStr + " " + data.getClockInTimeStr());
                    data.setClockInTime(inTime);
                }
            }

            // 3. 处理下班时间同理
            if (data.getClockOutTimeStr() != null && !data.getClockOutTimeStr().isEmpty()) {
                if (data.getAttendanceDate() != null) {
                    SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
                    dateFormatter.setTimeZone(shanghaiTimeZone); // 设置时区

                    // 处理"次日"的情况
                    String timeStr = data.getClockOutTimeStr();
                    if (timeStr.contains("次日")) {
                        timeStr = timeStr.replace("次日 ", ""); // 去掉"次日"字样
                        Calendar calendar = Calendar.getInstance();
                        calendar.setTime(data.getAttendanceDate());
                        calendar.add(Calendar.DAY_OF_MONTH, 1); // 加一天
                        String dateStr = dateFormatter.format(calendar.getTime());
                        SimpleDateFormat timeFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                        timeFormatter.setTimeZone(shanghaiTimeZone); // 设置时区
                        Date outTime = timeFormatter.parse(dateStr + " " + timeStr);
                        data.setClockOutTime(outTime);
                    } else {
                        SimpleDateFormat timeFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                        timeFormatter.setTimeZone(shanghaiTimeZone); // 设置时区

                        String dateStr = dateFormatter.format(data.getAttendanceDate());
                        Date outTime = timeFormatter.parse(dateStr + " " + timeStr);
                        data.setClockOutTime(outTime);
                    }
                }
            }
        } catch (Exception e) {
            log.error("日期时间转换错误: {}", data, e);
        }
    }
}
